/*******************************************************************************
 * 创建: 2024年10月18日
 * 作者: 水煮肉片饭(27185709@qq.com)
 * 描述: 屏幕适配器，让页面自动适配屏幕尺寸
 *      如果是多场景项目，在每个场景中需要新建一个页面根节点，所有页面内容都是该节点的子节点，将ScreenAdapter挂到根节点上。
 *      如果是单场景多预制体项目，就挂到页面预制体的根节点，推荐采用该方案
 * 主要会做以下适配：
 *     1、方向适配，根据页面尺寸，自动做横竖屏翻转
 *     2、尺寸适配，根据页面尺寸，自动拉伸到全屏 或 等比缩放
 *     3、坐标适配，将页面在设备窗口居中显示
 *     4、动态适配，如果设备窗口尺寸改变，游戏窗口会根据以上3个原则动态适配
*******************************************************************************/
import * as cc from 'cc';
import { DEV } from 'cc/env';
const { ccclass, property, menu } = cc._decorator;
const AUTO_ROTATE = true;      //是否开启自动旋转
const ROTATE_TIME = 1;         //屏幕旋转时长
export enum AdapterMode { 无, 拉伸全屏, 等比缩放 }
@ccclass('ScreenAdapter')
@menu('Public/ScreenAdapter')
export class ScreenAdapter extends cc.Component {
    @property({ type: cc.Enum(AdapterMode), displayName: DEV && '适配模式' })
    private adapterMode: AdapterMode = AdapterMode.等比缩放;
    protected onLoad() {
        let wgt = this.node.getComponent(cc.Widget);
        wgt && (wgt.enabled = false);
        this.updateAdapter();
        cc.view.on('canvas-resize', this.updateAdapter, this);
    }
    private updateAdapter() {
        let winSize = cc.view.getVisibleSize();
        let ut = this.node._uiProps['_uiTransformComp'] ?? this.node.addComponent(cc.UITransform);
        if (AUTO_ROTATE) {
            let camera = cc.director.getScene().getComponentInChildren(cc.Camera);
            if (camera) {
                let designSize = cc.view.getDesignResolutionSize();
                if (ut.width < ut.height === designSize.width < designSize.height) {
                    camera.node.angle !== 0 && cc.tween(camera.node).to(ROTATE_TIME, { angle: 0 }, { easing: 'expoOut' }).start();
                } else {
                    [winSize.width, winSize.height] = [winSize.height, winSize.width];
                    camera.node.angle !== -90 && cc.tween(camera.node).to(ROTATE_TIME, { angle: -90 }, { easing: 'expoOut' }).start();
                }
            }
        }
        switch (this.adapterMode) {
            case AdapterMode.拉伸全屏:
                this.node.setScale(winSize.width / ut.width, winSize.height / ut.height);
                this.node.setPosition(winSize.width * (ut.anchorX - 0.5), winSize.height * (ut.anchorY - 0.5));
                break;
            case AdapterMode.等比缩放:
                let scale = winSize.width / winSize.height > ut.width / ut.height ? winSize.height / ut.height : winSize.width / ut.width;
                this.node.setScale(scale, scale);
                this.node.setPosition(ut.width * scale * (ut.anchorX - 0.5), ut.height * scale * (ut.anchorY - 0.5));
                break;
        }
    }
    protected onDestroy() {
        cc.view.off('canvas-resize', this.updateAdapter, this);
    }
}